#include "tcptransfer.h"
#include "Threadbase/findmssqldatathread.h"
#include <QSqlQuery>
#include <QFile>
#include <QCoreApplication>
#include <QJsonParseError>
#include <QSqlError>
#include <qsqlrecord.h>
TcpTransFer::TcpTransFer(QObject *parent):QObject{parent},retryCount(0),maxRetry(10)
{
    socket = new QTcpSocket(this);
    reconnectTimer = new QTimer(this);
    reconnectTimer->setInterval(1000);

    connect(reconnectTimer,&QTimer::timeout,this,&TcpTransFer::tryConnect);
    connect(socket,&QTcpSocket::connected,this,&TcpTransFer::onConnected);
    connect(socket,&QTcpSocket::disconnected,this,&TcpTransFer::onDisConnected);
    connect(socket,&QTcpSocket::readyRead,this,&TcpTransFer::onReadyToRead);

    connect(this,&TcpTransFer::dataIsReady,this,&TcpTransFer::StartRunThread);

    CheckDataTimer = new QTimer(this);
    CheckDataTimer->setInterval(1000);
    connect(CheckDataTimer,&QTimer::timeout,this,&TcpTransFer::CheckData);

    db = QSqlDatabase::addDatabase("QODBC","transfData");
    db.setHostName("127.0.0.1");
    db.setUserName("ARNTUSER");
    db.setPassword("ARNTUSER");
    db.setDatabaseName("SteelRecord");
    if(!db.open()){
        qDebug()<<"打开数据库SteelRecord失败!";
        qDebug() << "Database error:" << db.lastError().text();
    }
}

void TcpTransFer::tryConnect()
{
    if(retryCount >= maxRetry){
        qDebug()<<"重连次数过多,退出链接";
        reconnectTimer->stop();
        return;
    }
    if(socket->state() == QAbstractSocket::UnconnectedState){
        qDebug()<<"正在尝试第"<<(retryCount+1)<<"次链接....";
        socket->abort();//断开之前的链接
        socket->connectToHost(host,port);
        retryCount++;
    }
}

void TcpTransFer::onConnected()
{
    qDebug()<<"链接成功";
    reconnectTimer->stop();
    //通信链接成功了才去检测并发送
    CheckDataTimer->start();
}

void TcpTransFer::onDisConnected()
{
    qDebug()<<"与服务器断开链接...";
}

void TcpTransFer::onReadyToRead()
{
    QByteArray responseData = socket->readAll();
    qDebug() << "从服务端接收数据<<<<:" << responseData;

    //数据处理
    int jsonStartIndex = responseData.indexOf('{');
    if (jsonStartIndex != -1) {
        QString jsonString = responseData.mid(jsonStartIndex);//提取字符串
        QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
            if(jsonDoc.isObject()){
            /*
            接收格式
000066R1K112D{
"recvStatus":"0","steelName":"T1000","cSlabNo":"BP123"
}
            recvStatus ：0代表成功接收 steelName 卷号 cSlabNo坯号
             */
            QJsonObject jsonObj = jsonDoc.object();
            QString recvStatus = jsonObj["recvStatus"].toString();
            QString steelName = jsonObj["steelName"].toString();
            QString cSlabNo = jsonObj["cSlabNo"].toString();
            qDebug()<<"当前接收状态"<<recvStatus<<"卷号"<<steelName<<"铸坯号"<<cSlabNo;
            emit dataIsReady(steelName,cSlabNo);
        }
    }

}

void TcpTransFer::startConnection(const QString &host, quint16 port)
{
    this->host = host;
    this->port = port;
    retryCount = 0;
    reconnectTimer->start();
}

void TcpTransFer::SendData(const QString &steelName)
{
    //先将数据变成特定的格式
    auto strData = formatData(steelName);
    //向服务器发送数据并写入到本地
    qDebug()<<"发送格式"<<strData;
    if(!socket->isOpen() || socket->state() != QAbstractSocket::ConnectedState){
        qDebug()<<"Socket断开重新链接";
        socket->abort();//断开之前的链接
        socket->connectToHost(host,port);
    }
    socket->write(strData.toUtf8());
    // socket->flush();

}

QString TcpTransFer::formatData(const QString &steelName)
{
    QJsonObject obj;
    obj["steelName"] = steelName;

    QString xml;
    xml+="K1T112";
    xml+="D";
    QJsonDocument jsonDoc(obj);
    QByteArray jsonByteArray = jsonDoc.toJson(QJsonDocument::Compact);
    xml+=jsonByteArray;
    xml += "\n";
    xml.prepend(QString("%1").arg(xml.length()+6,6,10,QLatin1Char('0')));

    SaveToFile((QCoreApplication::applicationDirPath()+"/FullProcessDataTransfer_Last_Record.json" ),obj);
    return xml;
}



void TcpTransFer::CheckData()
{
    //1.查询数据库 检测数据是否是最新
    QString sqlStr = R"(
    SELECT *
    FROM  [SteelRecord].[dbo].[SteelID]
    ORDER BY AddTime DESC
    OFFSET 1 ROW FETCH NEXT 1 ROW ONLY;
    )";
    QSqlQuery query(db);
    query.exec(sqlStr);
    if(query.next()){
        //当前查询到的卷号
        QString curSteelName = query.record().value("ID").toString();
        //检测是否和序列化的数据是相同的
        QJsonObject jsonObj= ReadToFile( (QCoreApplication::applicationDirPath()+"/FullProcessDataTransfer_Last_Record.json" ) );

        if(!jsonObj.isEmpty() && jsonObj["steelName"].toString().compare(curSteelName) != 0){
            qDebug()<<"当前准备发送的卷号:"<< curSteelName << " 本地存储的卷号:  "<<jsonObj["steelName"].toString() ;
            SendData(curSteelName);
        }
    }
}

void TcpTransFer::SaveToFile(const QString &fileName, const QJsonObject &jsonObj)
{
    QFile file(fileName);
    if (file.open(QIODevice::WriteOnly)) {
        QJsonDocument doc(jsonObj);
        file.write(doc.toJson());
        file.close();
    } else {
        qDebug() << "Failed to open file for writing";
    }
}

QJsonObject TcpTransFer::ReadToFile(const QString &fileName)
{
    QFile file(fileName);
    if(!file.exists()){
        if (!file.open(QIODevice::WriteOnly)) {
            qDebug() << "Failed to create file:" << file.errorString();
            return QJsonObject();
        }
        QJsonObject obj;
        obj["steelName"] = 0;
        QJsonDocument doc(obj);
        file.write(doc.toJson());
        file.close();
        return doc.object();
    }

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "文件访问失败" << file.errorString() <<fileName;
        return QJsonObject();  // 返回空的 QJsonObject
    }
    QByteArray fileData = file.readAll();
    file.close();
    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(fileData, &parseError);
    if (parseError.error != QJsonParseError::NoError) {
        qDebug() << "Failed to parse JSON:" << parseError.errorString();
        return QJsonObject();  // 返回空的 QJsonObject
    }
    if(jsonDoc.isObject()){
        return jsonDoc.object();
    }
    return QJsonObject();
}

void TcpTransFer::StartRunThread(QString name, QString parentName)
{
    FindMssqlDataThread *thread = new FindMssqlDataThread(name, parentName);;
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    thread->start();
    thread->wait();//等待线程执行结束
}

